﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Web;
using System.Web.Mvc;
using AliyunMobileTestPlatform.Models;
using System.Xml.Serialization;
using SharpSvn;
using SharpSvn.Security;
using System.Net;
using System.Web.Security;
using System.Web.Configuration;
using System.Security.Principal;

namespace AliyunMobileTestPlatform.Controllers
{
    public class ProjectsController : Controller
    {
        private static List<ProjectModel> pc;
        private static string REPOISTORY_ROOT_PATH = WebConfigurationManager.AppSettings["REPOISTORY_ROOT_PATH"].ToString();//@"D:\SVNServer\Repositories\";
        private static string PROJECTS_INFO_FILE_PATH = REPOISTORY_ROOT_PATH + "projects.xml";//@"D:\SVNServer\Repositories\projects.xml";
        private static string LOCALURL = WebConfigurationManager.AppSettings["LOCALURL"].ToString();//"https://localhost:8443/svn/";
        private static string URL = WebConfigurationManager.AppSettings["URL"].ToString();//"https://alibaba_65235n.hz.ali.com:8443/svn/";
        private static string BUILTIN_ADMIN = WebConfigurationManager.AppSettings["BUILTIN_ADMIN"].ToString();//"SvnAdmin";
        private static string BUILTIN_PWD = WebConfigurationManager.AppSettings["BUILTIN_PWD"].ToString();//"Aliyun123";
        private static string BUILTIN_DOMAIN = WebConfigurationManager.AppSettings["BUILTIN_DOMAIN"].ToString();//"ALIBABA_65235N";
        private static string ADMIN_SID_STR = ((SecurityIdentifier)(new NTAccount(BUILTIN_ADMIN).Translate(typeof(SecurityIdentifier)))).ToString();//"S-1-5-21-3535859988-1541617577-3489553981-1010";
        private static string VISUALSVN_WINAUTHZ_FILENAME = "VisualSVN-WinAuthz.ini";
        //
        // GET: /Projects/
        public ActionResult MainView()
        {
            if (pc==null)
            {
                using (FileStream fs = System.IO.File.OpenRead(PROJECTS_INFO_FILE_PATH))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(List<ProjectModel>));
                    pc = serializer.Deserialize(fs) as List<ProjectModel>;
                }
            }
            return View(pc);
        }

        //
        // POST: /Projects/AddBranch
        [HttpPost]
        public ActionResult AddBranch(FormCollection form)
        {
            try 
            {
                bool result = false;
                string pName=form.GetValue("beloneProjName").AttemptedValue.Trim();
                string bName=form.GetValue("addBranchName").AttemptedValue.Trim();
                using (SvnClient client = new SvnClient())
                {
                    SvnCreateDirectoryArgs args=new SvnCreateDirectoryArgs();
                    args.LogMessage="Add new branch";
                    
                    client.Authentication.Clear();
                    client.Authentication.DefaultCredentials = new NetworkCredential(BUILTIN_ADMIN, BUILTIN_PWD,BUILTIN_DOMAIN);
                    client.Authentication.SslServerTrustHandlers += delegate(object sender, SvnSslServerTrustEventArgs e)
                    {
                        e.AcceptedFailures = e.Failures;
                        e.Save = true; 
                    };
                    List<Uri> paths=new List<Uri>();
                    string path = LOCALURL + pName+"/" + bName;
                    paths.Add(new Uri(path));
                    paths.Add(new Uri( path + "/trunk"));
                    paths.Add(new Uri(path + "/branches"));
                    paths.Add(new Uri(path + "/tags"));
                    paths.Add(new Uri(path + "/histroy"));
                    result = client.RemoteCreateDirectories(paths, args);
                    
                }
                if (pc != null && result)
                {
                    foreach (ProjectModel pm in pc)
                    {
                        if (pm.ProjectName.Equals(pName))
                        {
                            BranchModel bm = new BranchModel();
                            bm.Name=bName;
                            bm.Repository = URL + pName + "/" + bName;
                            pm.Branches.Add(bm);
                            using (FileStream fs = new FileStream(PROJECTS_INFO_FILE_PATH, FileMode.Truncate))
                            {
                                XmlSerializer serializer = new XmlSerializer(typeof(List<ProjectModel>));
                                serializer.Serialize(fs, pc);
                            }
                            break;
                        }
                    }
                }  
                return RedirectToAction("MainView");
            }
            catch
            {
                return RedirectToAction("MainView");
            }
        }

        //
        // POST: /Projects/Create
        [HttpPost]
        public ActionResult Create(FormCollection form)
        {
            bool result = false;
            string path=REPOISTORY_ROOT_PATH + form.GetValue("creProjName").AttemptedValue;
            try
            {
                using (SvnRepositoryClient client = new SvnRepositoryClient())
                {
                    result=client.CreateRepository(path);
                }
                if (pc != null&&result)
                {
                    //添加权限配置文件
                    using (FileStream fs = new FileStream(path + @"\conf\" + VISUALSVN_WINAUTHZ_FILENAME, FileMode.Create))
                    {
                        using (StreamWriter sw = new StreamWriter(fs)) 
                        {
                            sw.WriteLine(@"[/]");
                            sw.WriteLine(ADMIN_SID_STR+"=rw");
                        }
                    }

                    //添加项目信息
                    ProjectModel pm = new ProjectModel();
                    pm.ProjectName = form.GetValue("creProjName").AttemptedValue;
                    pm.ID = pm.ProjectName.Replace(' ', '_');
                    pm.HardwareInfo = form.GetValue("hardwareInfo").AttemptedValue;
                    pm.SoftwareInfo = form.GetValue("softwareInfo").AttemptedValue;
                    pc.Add(pm);
                    using (FileStream fs = new FileStream(PROJECTS_INFO_FILE_PATH, FileMode.Truncate))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(List<ProjectModel>));
                        serializer.Serialize(fs, pc);
                    }
                }  
                return RedirectToAction("MainView");
            }
            catch
            {
                return RedirectToAction("MainView");
            }
        }
        
        //
        // POST: /Projects/Edit
        [HttpPost]
        public ActionResult Edit(FormCollection form)
        {
            if (pc!=null)
            {
                foreach (ProjectModel pm in pc) 
                {
                    if (pm.ID.Equals(form.GetValue("pid").AttemptedValue)) 
                    {
                        pm.HardwareInfo = form.GetValue("hardwareInfo").AttemptedValue;
                        pm.SoftwareInfo = form.GetValue("softwareInfo").AttemptedValue;
                        using (FileStream fs = new FileStream(PROJECTS_INFO_FILE_PATH, FileMode.Truncate))
                        {
                            XmlSerializer serializer = new XmlSerializer(typeof(List<ProjectModel>));
                            serializer.Serialize(fs, pc);
                        }
                        break;
                    }
                }
            }           
            return RedirectToAction("MainView");
        }

        //
        // POST: /Projects/Delete
        [HttpPost]
        public ActionResult Delete(FormCollection form)
        {
            try
            {
                bool result = false;
                if (form.GetValue("delType").AttemptedValue.Trim().Equals("project")) 
                {
                    string delName=form.GetValue("delName").AttemptedValue.Trim();
                    using (SvnRepositoryClient client = new SvnRepositoryClient()) 
                    {
                        result=client.DeleteRepository(REPOISTORY_ROOT_PATH + delName);
                    }
                    if (result && pc != null) 
                    {
                        for (int i = 0; i < pc.Count; i++) 
                        {
                            if (pc[i].ProjectName.Equals(delName)) 
                            {
                                pc.RemoveAt(i);
                                using (FileStream fs = new FileStream(PROJECTS_INFO_FILE_PATH, FileMode.Truncate))
                                {
                                    XmlSerializer serializer = new XmlSerializer(typeof(List<ProjectModel>));
                                    serializer.Serialize(fs, pc);
                                }
                                return RedirectToAction("MainView");
                            }
                        }
                    }
                }
                else if (form.GetValue("delType").AttemptedValue.Trim().Equals("branch")) 
                {
                    string[] pb = form.GetValue("delName").AttemptedValue.Trim().Split('@');

                    using (SvnClient client = new SvnClient()) 
                    {
                        client.Authentication.Clear();
                        client.Authentication.DefaultCredentials = new NetworkCredential(BUILTIN_ADMIN, BUILTIN_PWD, BUILTIN_DOMAIN);
                        client.Authentication.SslServerTrustHandlers += delegate(object sender, SvnSslServerTrustEventArgs e)
                        {
                            e.AcceptedFailures = e.Failures;
                            e.Save = true;
                        };
                        SvnDeleteArgs delArgs = new SvnDeleteArgs();
                        delArgs.LogMessage = "Delete branch " + pb[1] + " of " + pb[0];
                        result=client.RemoteDelete(new Uri(LOCALURL + pb[0] + "/" + pb[1]),delArgs);
                    }
                    if (result && pc != null) 
                    {
                        foreach (ProjectModel pm in pc)
                        {
                            if (pm.ProjectName.Equals(pb[0]))
                            {
                                for (int i = 0; i < pm.Branches.Count;i++ )
                                {
                                    if (pm.Branches[i].Name.Equals(pb[1])) 
                                    {
                                        pm.Branches.RemoveAt(i);
                                        using (FileStream fs = new FileStream(PROJECTS_INFO_FILE_PATH, FileMode.Truncate))
                                        {
                                            XmlSerializer serializer = new XmlSerializer(typeof(List<ProjectModel>));
                                            serializer.Serialize(fs, pc);
                                        }
                                        return RedirectToAction("MainView");
                                    }
                                }                               
                            }
                        }
                    }
                }
                return RedirectToAction("MainView");
            }
            catch
            {
                return RedirectToAction("MainView");
            }
        }
    }
}
